#include <iostream>
#include <string>
#include <cstdlib>
#include <unistd.h>
#include <signal.h>
#include <unistd.h>

using namespace std;

int cnt = 0;
int n = 0;

void handler(int signo)
{
    // n = alarm(2); 
    n = alarm(0); //如果提前向该进程发送14好信号的话，n中就保存上次闹钟剩余的时间
    // cout<< "cnt  :  " << cnt << endl;
    cout << "result :  " << n << endl;
    cout << "获取到一个" << signo << "信号" << endl;
    // sleep(1);
    // exit(0);
}

// 产生信号的三种方式：
// 1. 通过键盘产生 ctrl + c(2)  ctrl + z (20) ctrl + \ (3)  当键盘上输入数据的时候触达对应中断cpu识别到对应的中断
// 号，然后用中断号索引对应的中断向量表（函数指针数组，有对应设备的读取方法），然后将数据拿到os,os进行识别，发现是组合键，然后转化为信号，
// 向指定进程发送（1.linux下前台进程只有一个，os作为进程的管理者当然可以知道要给那一个进程发。2.所谓的发信号实际上就是向目标进程的pcb中写信号位图)
// 然后将信号存储起来，在合适的时候处理在这些信号（那么进程里面对于这些信号就要做出管理，即通过信号位图来管理（对应bit为标记是否存在，对应编号标记是几号信号））

// 2. kill(和kill命令行使用方法一样)
//  raise 向自己发送信号
//  abort 给自己发送一个6号信号

// 3.异常（exception）
// 除0 exception 这里为为什么会死循环在运算的的时候出现错误硬件第一时间发现被除数为0 马上将溢出标志位（寄存器） 标记为 1，然后有硬件向os
// 发送中断，然后OS向目标进程发信号，执行对应的信号处理方法，又因为有自定义捕获动作中没有exit() ，这个时候因为有异常所以程序不向后执行，os调度其他进程
// 然后保存当前进程硬件上下文（包括溢出标记位），然后os再调度这个进程，所以重复上面过程就是一个死循环

// 4.软件条件（闹钟）alarm
//

int main(int argc, char *argv[])
{

    signal(14, handler);
    alarm(2);
    while (1)
    {
        // cout << "runing...." << cnt++ << endl;
        // cnt++;
        cout << "runing ..., pid  : " << getpid() << endl;
        sleep(1);
    }

    // signal(11,handler);
    // int* p = nullptr;
    // *p = 1;

    // signal(8,handler);
    // int a = 10 / 0;
    // signal(6,handler);
    // cout<< "start" <<endl;

    // abort();

    // cout<< "end" <<endl;

    // signal(2,handler);
    // sleep(5);
    // int n = raise(2);

    // sleep(5);

    // if(argc != 3)
    // {
    //     cout<< "./process "<< "-signo "<< "pid"<<endl;
    //     exit(1);
    // }

    // int signo = stoi(argv[1] + 1);
    // int pid = stoi(argv[2]);

    // kill(pid,signo);

    // //自定义捕捉，但是有一些信号不能够被自定义捕捉
    // signal(3,handler);
    // signal(2,handler);
    // signal(20,handler);
    // signal(19,handler);
    // int cnt = 1;
    // while(true)
    // {
    //     std::cout<<"runing...  : " << cnt++ << ",pid : " << getpid()<<std::endl;
    //     sleep(1);
    // }
    return 0;
}
